from typing import Any, Optional

from fastapi import APIRouter, Depends, HTTPException, Response, status
from sqlalchemy import desc, and_

import models
import schemas
from libs.dependencies import Utils, UtilsObject
import requests
import json
import time
router = APIRouter()
local_token = {}
v_one_url = 'http://auth.vvtechnology.cn'


@router.options('/services')
def option_services():
    return


@router.post('/services')
def get_services(queryInfo: schemas.ServicesQuery, utils: UtilsObject = Depends(Utils(False))):
    # 获取用户token,强制刷新或者token失效（不在同一天），重新获取token，及服务信息
    users = utils.db.session.query(models.VOne).filter(models.VOne.userName == queryInfo.userName).first()
    if queryInfo.reFlush or users is None or not users.token or time.strftime("%Y-%m-%d", time.localtime(users.lastTime/1000)) != time.strftime("%Y-%m-%d", time.localtime()):
        res = requests.post(v_one_url + '/vvauth/auth/login',
                            json.dumps({'loginName': queryInfo.userName,
                                        'password': queryInfo.password,
                                        'auto': True}),
                            headers={'Content-Type': 'application/json'})
        if users is None:
            users = models.VOne(**{'userName': queryInfo.userName, 'password': queryInfo.password, 'token': json.loads(res.text)['data']['token'], 'lastTime': int(round(time.time() * 1000))})
            utils.db.session.add(users)
        else:
            users.password = queryInfo.password
            users.lastTime = int(round(time.time() * 1000))
            users.token = json.loads(res.text)['data']['token']
        res = requests.get(v_one_url + '/wb/v1.0/products/list',
                           headers={'Authorization': users.token,
                                    'Content-Type': 'application/json'})
        for services_team in json.loads(res.text):
            if services_team['name'] in ['vvwork', '基础服务']:
                res = requests.get(v_one_url + '/wb/v1.0/products/services/list?productId=' + str(services_team['id']),
                                   headers={'Authorization': users.token,'Content-Type': 'application/json'})
                for s in json.loads(res.text):
                    res_info = requests.get(v_one_url + '/wb/v1.0/deploys/last_run_info_list?serviceId=' + str(s['id']),
                                            headers={'Authorization': users.token,
                                                     'Content-Type': 'application/json'})
                    for item in json.loads(res_info.text):
                        service = utils.db.session.query(models.VOneService).filter(models.VOneService.serviceId == item['deployConfigId']).first()
                        if not service:
                            vo = models.VOneService(**{'env': item['envName'], 'serviceName': item['deployConfigName'],
                                                       'serviceCode': s['name'], 'serviceId': item['deployConfigId'],
                                                       'watchUser': queryInfo.userName})
                            utils.db.session.add(vo)
                        else:
                            old_users = service.execUser.split(',') if service.execUser else []
                            old_users.append(queryInfo.userName)
                            service.watchUser = ','.join(list(set(old_users)))
        utils.db.session.commit()

    # 获取service信息，动态获取最新运行状态，返回信息
    result = []
    for watch_service in utils.db.session.query(models.VOneService).filter(and_(models.VOneService.serviceName.like('%' + queryInfo.env + '%'), models.VOneService.watchUser.like('%' + queryInfo.userName + '%'))).all():
        res = requests.get(v_one_url + '/wb/v1.0/deploys/' + watch_service.serviceId + '/last_run_info_detail',
                           headers={'Authorization': users.token, 'Content-Type': 'application/json'})
        res_dict = json.loads(res.text)
        old_users = watch_service.execUser.split(',') if watch_service.execUser else []
        old_users.append(queryInfo.userName)
        watch_service.execUser = watch_service.execUser if res_dict['enableRun'] is False else ','.join(list(set(old_users)))
        watch_dict = watch_service.to_dict()
        watch_dict['run'] = res_dict['enableRun'] if res_dict['enableRun'] else False
        watch_dict['status'] = res_dict['status']
        watch_dict['runUser'] = res_dict['runUserName']
        watch_dict['lastTime'] = res_dict['startTime']
        watch_dict['itemId'] = res_dict['deployConfigId']
        watch_dict['lastTag'] = res_dict['branchName']
        # if res_dict['sources'] and len(res_dict['sources']) > 0:
        #     watch_dict['itemId'] = res_dict['sources'][0]['id']
        #     watch_dict['lastTag'] = res_dict['sources'][0]['branchName']
        # else:
        #     rs = requests.get(v_one_url + '/wb/v1.0/pipelines/' + watch_service.serviceId + '/running_config_params',
        #                       headers={'Authorization': users.token, 'Content-Type': 'application/json'})
        #     watch_dict['itemId'] = json.loads(rs.text)['sources'][0]['id']
        #     watch_dict['lastTag'] = ''
        result.append(watch_dict)
    return {'code': 10000, 'msg': 'success', 'data': result}


@router.options('/run')
def option_run():
    return


@router.post('/run')
def run_services(buildInfo: schemas.BuildInfo, response: Response, utils: UtilsObject = Depends(Utils(False))):
    users = utils.db.session.query(models.VOne).filter(models.VOne.userName == buildInfo.userName).first()
    if not users or not users.token or time.strftime("%Y-%m-%d", time.localtime(users.lastTime/1000)) != time.strftime("%Y-%m-%d", time.localtime()):
        response.status_code = status.HTTP_203_NON_AUTHORITATIVE_INFORMATION
        return {'code': 10031, 'msg': 'success', 'data': ''}
    for service in buildInfo.serviceList:
        requests.post(v_one_url + '/wb/v1.0/deploys/actions/run',
                      json.dumps({'branchName': service.lastTag,
                                  'deployConfigId': service.itemId}),
                      headers={'Authorization': users.token, 'Content-Type': 'application/json'})
    return {'code': 10000, 'msg': 'success', 'data': ''}
